package com.springmvc.init.handlerMapping;

import com.springmvc.annotation.RequestMapping;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.config.InstantiationAwareBeanPostProcessor;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;

import java.lang.reflect.Method;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

@Component
public class AnnotationHandlerMapping implements InstantiationAwareBeanPostProcessor, HandlerMapping {

    private final Map<String, RequestMethodInfo> requestMethodInfoMap = new ConcurrentHashMap<>(8);

    @Override
    public Object gethandlerMapping(String requestUrl) {
        return requestMethodInfoMap.get(requestUrl);
    }

    @Override
    public boolean postProcessAfterInstantiation(Object bean, String beanName) throws BeansException {
        Class<?> beanClass = bean.getClass();
        if (beanClass.isAnnotationPresent(Controller.class)) {
            Method[] declaredMethods = beanClass.getDeclaredMethods();
            for (Method declaredMethod : declaredMethods) {
                if (declaredMethod.isAnnotationPresent(RequestMapping.class)) {
                    RequestMethodInfo info = new RequestMethodInfo();
                    info.setMethod(declaredMethod);
                    info.setTarget(bean);
                    info.setUrl(declaredMethod.getAnnotation(RequestMapping.class).value());
                    requestMethodInfoMap.put(info.getUrl(), info);
                }
            }
        }
        return true;
    }
}
